home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / Drivers / vc_2_2.lha / ParNet / Source / unit_dgr.c < prev    next >
C/C++ Source or Header  |  1994-11-01  |  4KB  |  211 lines

  1. /*
  2. ** $Header: SRC:CVSROOT/Vector/ParNet/unit_dgr.c,v 1.1.1.1 1994/06/23 02:39:42 Barnard Exp $
  3. */
  4.  
  5. /*
  6. ** This code was originally written by Matthew Dillon and put into Public Domain
  7. **
  8. ** All changes concerning the adaption of Matt's original code to the
  9. ** Vector Connection I/O board are © 1991-1994 by Henning Schmiedehausen
  10. ** All rights for this changes are reserved. The original code is Public Domain
  11. **
  12. ** This code is distributed with the expressed written permission of Matthew
  13. ** Dillon (Thank you very much, Matt)
  14. **
  15. */
  16.  
  17. /*
  18.  *  UNIT_DGR.C            DATAGRAM PROTOCOL
  19.  */
  20.  
  21. #include "defs.h"
  22.  
  23. #include "unit_dgr_protos.h"
  24. #include "unit_ctl_protos.h"
  25. #include "parnet_protos.h"
  26. #include "task_protos.h"
  27.  
  28. #include <proto/exec.h>
  29. #include <stdlib.h>
  30. #include <stddef.h>
  31. #include <string.h>
  32.  
  33. #include "parnet_asm.h"
  34.  
  35.  
  36. void DGramBeginIO();
  37. void DGramAbortIO();
  38. void DGramClose();
  39. void DGramData();
  40.  
  41. /*
  42.  *  Called under Forbid
  43.  */
  44.  
  45. void
  46. UnitDGramOpen(iob, unitnum, flags)
  47. Iob *iob;
  48. long unitnum;
  49. long flags;
  50. {
  51.     Unit *unit;
  52.  
  53.     if (unit = FindUnitForPort(iob->io_Port)) {
  54.     if (unit->BeginIO != DGramBeginIO) {
  55.         iob->io_Error = PPERR_PORT_IN_USE;
  56.         return;
  57.     }
  58.     } else {
  59.     unit = AllocUnit(iob, DGramBeginIO, DGramAbortIO, DGramData, DGramClose);
  60.     }
  61.     iob->io_Unit = unit;
  62.     ++unit->RefCnt;
  63. }
  64.  
  65.  
  66. void
  67. DGramClose(iob)
  68. Iob *iob;
  69. {
  70.     Unit *unit = iob->io_Unit;
  71.  
  72.     if (--unit->RefCnt == 0) {
  73.     FreeUnit(unit);
  74.     }
  75.     iob->io_Unit = NULL;
  76. }
  77.  
  78. /*
  79.  *  UnitDGramData() is called whenever a low level network operation
  80.  *            completes for the given unit.  cmd is:
  81.  *
  82.  *            'r'     received data packet
  83.  *            'w'     wrote data packet
  84.  *            'W'     timeout writing data packet
  85.  *
  86.  *            The routine is called with the unix locked.
  87.  *
  88.  *  WARNING:    This call may not requeue synchronous packets, a lockout
  89.  *        will result.
  90.  */
  91.  
  92. void
  93. DGramData(cmd, packet, actual)
  94. Packet *packet;
  95. long actual;    /*  'w', 'W'    */
  96. {
  97.     Unit *unit = packet->io_Unit;
  98.     Iob *iob = packet->iob;        /*    NULL for 'r'    */
  99.     long n;
  100.  
  101.     switch(cmd) {
  102.     case 'r':
  103.     if (iob = (Iob *)RemHead(&unit->PendIOR)) {
  104.         iob->io_Flags &= ~IOF_QUEUED;
  105.  
  106.         n = actual;
  107.         if (n < 0)
  108.         n = 0;
  109.         if (n > iob->io_Length) {
  110.         n = iob->io_Length;
  111.         iob->io_Error = PPERR_WARN_OVFLOW;
  112.         }
  113.         actual -= n;
  114.         movmem((char *)packet->Data1, (char *)iob->io_Data, n);
  115.  
  116.         if (iob->io_Length2 && actual > 0) {    /*  a second data buffer    */
  117.         if (actual > iob->io_Length2)
  118.             actual = iob->io_Length2;
  119.         movmem((char *)packet->Data1 + n, (char *)iob->io_Data2, actual);
  120.         n += actual;
  121.         }
  122.         iob->io_Actual = n;
  123.  
  124.         if ((iob->io_Flags & IOF_QUICK) == 0)
  125.         ReplyMsg(&iob->io_Message);
  126.     }
  127.  
  128.     /*
  129.      *  Note that if no read requests are pending the datagram is
  130.      *  thrown away.
  131.      */
  132.  
  133.     FreeParPacket(packet);
  134.     break;
  135.     case 'W':
  136.     Remove(iob);
  137.     iob->io_Flags &= ~IOF_QUEUED;
  138.     iob->io_Error = 1;
  139.     iob->io_Actual = actual;
  140.     if ((iob->io_Flags & IOF_QUICK) == 0)
  141.         ReplyMsg(&iob->io_Message);
  142.     FreeParPacket(packet);
  143.     break;
  144.     case 'w':
  145.     Remove(iob);
  146.     iob->io_Flags &= ~IOF_QUEUED;
  147.     iob->io_Actual = actual;
  148.     if ((iob->io_Flags & IOF_QUICK) == 0)
  149.         ReplyMsg(&iob->io_Message);
  150.     FreeParPacket(packet);
  151.     break;
  152.     }
  153. }
  154.  
  155. void
  156. DGramBeginIO(iob)
  157. Iob *iob;
  158. {
  159.     Unit *unit = iob->io_Unit;
  160.     Packet *packet;
  161.  
  162.     iob->io_Error = 0;
  163.     iob->io_Actual = 0;
  164.     iob->io_Message.mn_Node.ln_Type = NT_MESSAGE;
  165.  
  166.     switch(iob->io_Command) {
  167.     case CMD_READ:
  168.     LockAddr(unit->UnitLock);
  169.     iob->io_Flags &= ~IOF_QUICK;
  170.     iob->io_Flags |= IOF_QUEUED;
  171.     AddTail(&unit->PendIOR, iob);
  172.     UnlockAddr(unit->UnitLock);
  173.     return;
  174.     case CMD_WRITE:
  175.     packet = AllocParPacket(iob, unit, iob->io_Data, iob->io_Length, iob->io_Data2, iob->io_Length2);
  176.     LockAddr(unit->UnitLock);
  177.     AddTail(&unit->PendIOW, iob);
  178.     UnlockAddr(unit->UnitLock);
  179.  
  180.     QueuePacketForWrite(packet);
  181.     return;
  182.     default:
  183.     CtlBeginIO(iob);
  184.     return;
  185.     }
  186. }
  187.  
  188. /*
  189.  *  Abort a read or write request.  Currently only read requests may be
  190.  *  aborted.
  191.  */
  192.  
  193. void
  194. DGramAbortIO(iob)
  195. Iob *iob;
  196. {
  197.     if (iob->io_Command == CMD_READ) {
  198.     LockAddr(iob->io_Unit->UnitLock);
  199.     if ((iob->io_Flags & (IOF_QUEUED|IOF_RUN)) == IOF_QUEUED) {
  200.         Remove(iob);
  201.         UnlockAddr(iob->io_Unit->UnitLock);
  202.         iob->io_Flags &= ~IOF_QUEUED;
  203.         iob->io_Error = -1;     /*    ??? */
  204.         ReplyMsg(&iob->io_Message);
  205.     } else {
  206.         UnlockAddr(iob->io_Unit->UnitLock);
  207.     }
  208.     }
  209. }
  210.  
  211.